package com.shinhye.elephantsafe.service;

import java.lang.reflect.Method;

import com.android.internal.telephony.ITelephony;
import com.shinhye.elephantsafe.db.dao.BlackListDao;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.util.Log;

public class TelephonySafeService extends Service {
	private final String TAG = "TelephonySafeService";
	private BlackListDao dao;
	private SmsBroadcastReceiver receiver;
	private TelephonyManager tm;
	private PhoneStateListener listener;

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@Override
	public void onCreate() {
		Log.i(TAG, "拦截服务启动了！");
		dao = new BlackListDao(this);
		
		tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		listener = new MyPhoneStateListener();
		tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
		
		//代码注册广播接收者
		receiver = new SmsBroadcastReceiver();
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
		intentFilter.setPriority(Integer.MAX_VALUE);
		registerReceiver(receiver, intentFilter);
	}
	
	//拦截来电的监听器
	private class MyPhoneStateListener extends PhoneStateListener {
		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			switch(state) {
			case TelephonyManager.CALL_STATE_RINGING:
				int mode = dao.find(incomingNumber);
				if(mode == 0 || mode == 2) {
					Log.i(TAG, "拦截来电！");
					
					Uri uri = Uri.parse("content://call_log/calls");
					getContentResolver().registerContentObserver(uri, false, new MyContentObserver(new Handler(), incomingNumber));
					
					endCall();
				}
				break;
			case TelephonyManager.CALL_STATE_OFFHOOK:
				break;
			case TelephonyManager.CALL_STATE_IDLE:
				break;
			}
		}
	}
	
	//自定义内容观察者观察通讯历史记录变化
	private class MyContentObserver extends ContentObserver {
		String number;
		public MyContentObserver(Handler handler, String number) {
			super(handler);
			this.number = number;
		}
		
		@Override
		public void onChange(boolean selfChange) {
			deleteCallLog(number);
			
			//必须在删除通讯日志后取消注册内容观察者
			getContentResolver().unregisterContentObserver(this);
		}
	}

	//自定义短信广播接收者，拦截短信
	private class SmsBroadcastReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent) {
			Object[] pdus = (Object[]) intent.getExtras().get("pdus");
			for (Object pdu : pdus) {
				SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu);
				String number = sms.getOriginatingAddress();
				
				//拦截含有关键字的广告短信
				String body = sms.getMessageBody();
				if(body.contains("发票")) {
					Log.i(TAG, "拦截了一条广告短信！来自：" + number);
					abortBroadcast();
				}
				
				//查找黑名单数据库
				int mode = dao.find(number);
				if(mode == -1)
					return;
				if(mode == 1 || mode == 2) {
					Log.i(TAG, "拦截了一条短信了！来自：" + number);
					abortBroadcast();
				}
				
			}
		}
	}
	
	@Override
	public void onDestroy() {
		Log.i(TAG, "拦截服务终止了！");
		super.onDestroy();
		
		//停止监听来电
		tm.listen(listener, PhoneStateListener.LISTEN_NONE);
		listener = null;
		
		//解注册广播接收者
		unregisterReceiver(receiver);
		receiver = null;
	}
	
	/**
	 * A method to reflect to system API-endCall. 
	 */
	public void endCall() {
		try {
			Class<?> clazz = TelephonySafeService.class.getClassLoader().loadClass("android.os.ServiceManager");
			Method method = clazz.getDeclaredMethod("getService", String.class);
			IBinder ib = (IBinder) method.invoke(null, TELEPHONY_SERVICE);
			ITelephony itel = ITelephony.Stub.asInterface(ib);
			itel.endCall();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void deleteCallLog(String number) {
		ContentResolver resolver = getContentResolver();
		Uri uri = Uri.parse("content://call_log/calls");
		resolver.delete(uri, "number=?", new String[]{number});
	}
}
